package com.lifeverse.repository;

import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.Resource;
import com.lifeverse.entity.enums.ResourceStatus;
import com.lifeverse.entity.enums.ResourceType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 资源数据访问接口
 */
@Repository
public interface ResourceRepository extends JpaRepository<Resource, Long> {
    
    /**
     * 根据名称查找资源
     */
    Optional<Resource> findByName(String name);
    
    /**
     * 根据类型查找资源
     */
    List<Resource> findByType(ResourceType type);
    
    /**
     * 根据状态查找资源
     */
    List<Resource> findByStatus(ResourceStatus status);
    
    /**
     * 根据拥有者查找资源
     */
    List<Resource> findByOwner(LifeEntity owner);
    
    /**
     * 根据当前使用者查找资源
     */
    List<Resource> findByCurrentUser(LifeEntity currentUser);
    
    /**
     * 根据类型和状态查找资源
     */
    List<Resource> findByTypeAndStatus(ResourceType type, ResourceStatus status);
    
    /**
     * 查找可用资源
     */
    @Query("SELECT r FROM Resource r WHERE r.status IN :availableStatuses")
    List<Resource> findAvailableResources(@Param("availableStatuses") List<ResourceStatus> availableStatuses);
    
    /**
     * 根据类型查找可用资源
     */
    @Query("SELECT r FROM Resource r WHERE r.type = :type AND r.status IN :availableStatuses")
    List<Resource> findAvailableResourcesByType(@Param("type") ResourceType type, 
                                              @Param("availableStatuses") List<ResourceStatus> availableStatuses);
    
    /**
     * 查找有足够容量的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.availableAmount >= :requiredAmount AND r.status IN :availableStatuses")
    List<Resource> findResourcesWithSufficientCapacity(@Param("requiredAmount") BigDecimal requiredAmount,
                                                      @Param("availableStatuses") List<ResourceStatus> availableStatuses);
    
    /**
     * 根据类型查找有足够容量的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.type = :type AND r.availableAmount >= :requiredAmount AND r.status IN :availableStatuses")
    List<Resource> findResourcesWithSufficientCapacityByType(@Param("type") ResourceType type,
                                                            @Param("requiredAmount") BigDecimal requiredAmount,
                                                            @Param("availableStatuses") List<ResourceStatus> availableStatuses);
    
    /**
     * 根据优先级排序查找资源
     */
    List<Resource> findByTypeOrderByPriorityDesc(ResourceType type);
    
    /**
     * 根据使用率查找资源
     */
    @Query("SELECT r FROM Resource r WHERE (r.usedAmount / r.capacity) >= :usageThreshold")
    List<Resource> findHighUsageResources(@Param("usageThreshold") BigDecimal usageThreshold);
    
    /**
     * 根据使用率查找资源
     */
    @Query("SELECT r FROM Resource r WHERE (r.usedAmount / r.capacity) <= :usageThreshold")
    List<Resource> findLowUsageResources(@Param("usageThreshold") BigDecimal usageThreshold);
    
    /**
     * 查找需要维护的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.nextMaintenanceAt IS NOT NULL AND r.nextMaintenanceAt <= :now")
    List<Resource> findResourcesNeedingMaintenance(@Param("now") LocalDateTime now);
    
    /**
     * 查找过期的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.expiresAt IS NOT NULL AND r.expiresAt <= :now")
    List<Resource> findExpiredResources(@Param("now") LocalDateTime now);
    
    /**
     * 查找长时间未使用的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.lastUsedAt IS NULL OR r.lastUsedAt < :threshold")
    List<Resource> findUnusedResources(@Param("threshold") LocalDateTime threshold);
    
    /**
     * 根据位置查找资源
     */
    List<Resource> findByLocation(String location);
    
    /**
     * 根据位置和类型查找资源
     */
    List<Resource> findByLocationAndType(String location, ResourceType type);
    
    /**
     * 分页查找资源
     */
    Page<Resource> findByType(ResourceType type, Pageable pageable);
    
    /**
     * 分页查找拥有者的资源
     */
    Page<Resource> findByOwner(LifeEntity owner, Pageable pageable);
    
    /**
     * 统计资源数量
     */
    long countByType(ResourceType type);
    
    /**
     * 统计状态资源数量
     */
    long countByStatus(ResourceStatus status);
    
    /**
     * 统计拥有者的资源数量
     */
    long countByOwner(LifeEntity owner);
    
    /**
     * 计算类型资源的总容量
     */
    @Query("SELECT SUM(r.capacity) FROM Resource r WHERE r.type = :type")
    BigDecimal sumCapacityByType(@Param("type") ResourceType type);
    
    /**
     * 计算类型资源的已使用量
     */
    @Query("SELECT SUM(r.usedAmount) FROM Resource r WHERE r.type = :type")
    BigDecimal sumUsedAmountByType(@Param("type") ResourceType type);
    
    /**
     * 计算类型资源的可用量
     */
    @Query("SELECT SUM(r.availableAmount) FROM Resource r WHERE r.type = :type")
    BigDecimal sumAvailableAmountByType(@Param("type") ResourceType type);
    
    /**
     * 查找成本最低的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.type = :type AND r.status IN :availableStatuses ORDER BY r.unitCost ASC")
    List<Resource> findCheapestResourcesByType(@Param("type") ResourceType type,
                                             @Param("availableStatuses") List<ResourceStatus> availableStatuses,
                                             Pageable pageable);
    
    /**
     * 查找性能最好的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.type = :type AND r.status IN :availableStatuses ORDER BY r.priority DESC, r.capacity DESC")
    List<Resource> findBestPerformanceResourcesByType(@Param("type") ResourceType type,
                                                     @Param("availableStatuses") List<ResourceStatus> availableStatuses,
                                                     Pageable pageable);
    
    /**
     * 根据关键词搜索资源
     */
    @Query("SELECT r FROM Resource r WHERE r.name LIKE %:keyword% OR r.description LIKE %:keyword% OR r.tags LIKE %:keyword%")
    List<Resource> findByKeyword(@Param("keyword") String keyword);
    
    /**
     * 查找即将过期的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.expiresAt IS NOT NULL AND r.expiresAt BETWEEN :now AND :threshold")
    List<Resource> findResourcesExpiringBetween(@Param("now") LocalDateTime now, @Param("threshold") LocalDateTime threshold);
    
    /**
     * 查找最近创建的资源
     */
    List<Resource> findTop10ByOrderByCreatedTimeDesc();
    
    /**
     * 查找最近使用的资源
     */
    @Query("SELECT r FROM Resource r WHERE r.lastUsedAt IS NOT NULL ORDER BY r.lastUsedAt DESC")
    List<Resource> findRecentlyUsedResources(Pageable pageable);
}